package com.sh.healthtv.net.service.envelop;

import com.sh.healthtv.net.entity.Definition;
import com.sh.healthtv.net.entity.DirtyListResult;
import com.sh.healthtv.net.entity.FaildBean;
import com.sh.healthtv.net.entity.MediaPlayList;
import com.sh.healthtv.net.service.IPolyManager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by zhouyucheng on 2017/8/4.
 */

public class PolyManager {
    private static PolyManager mPolyManager;

    private static final String divider = "/";

    private IPolyManager iPolyManager;

    private static final int DEFAULT_TIMEOUT = 5;

    /**
     * POLYPOART_ADDRESS,例如:http://192.168.3.20 方便调试
     */
    private String PORTAL_ADDRESS;

    private String regionCode;
    private String terminal_type;

    /**
     * 接口错误
     */
    public static String POLY_FAILD = "ERROR";

    private PolyManager(String portalAddress, String terminal_type, String regionCode) {
        this.regionCode = regionCode;
        this.terminal_type = terminal_type;
        if (portalAddress != null && portalAddress.trim().length() > 0) {
            if (!portalAddress.endsWith("/")) {
                this.PORTAL_ADDRESS = portalAddress + divider;
            } else {
                // 兼容老的项目
                this.PORTAL_ADDRESS = portalAddress;
            }
        }


        // An OkHttp interceptor which logs HTTP request and response data.
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
//        logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        //手动创建一个OkHttpClient并设置超时时间
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        httpClientBuilder.addInterceptor(logging);

        Retrofit mRetrofit = new Retrofit.Builder()
                .client(httpClientBuilder.build())
                .baseUrl(PORTAL_ADDRESS)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        iPolyManager = mRetrofit.create(IPolyManager.class);

    }

    public static PolyManager getInstence() {
        return mPolyManager;
    }


    private class DirtyListResultFactory<T> implements Func1<DirtyListResult<T>, MediaPlayList> {
        private Subscriber subscriber;

        public DirtyListResultFactory(Subscriber<T> sub) {
            this.subscriber = sub;
        }

        @Override
        public MediaPlayList call(DirtyListResult<T> tBaseBean) {
            if (tBaseBean == null) {
                /**
                 * API 17
                 */
                this.subscriber.onError(new Throwable(POLY_FAILD, new Throwable(FaildBean.RESULT_NULL + "", new Throwable(""))));
                return null;
            }
            String ret = tBaseBean.getRet();
            Map<String, Object> program = tBaseBean.getProgram();
            if ("0".equals(ret)) {
                List<Definition> list = (List<Definition>) tBaseBean.getList();

                for ( Definition info : list ){
                    info.setName(program.get("name").toString());
                    info.setDuration(program.get("duration").toString());
                }

                MediaPlayList media = new MediaPlayList();
                media.setList(list);
                media.setFavorite(tBaseBean.isFavorite());
                return media;
            } else {
                this.subscriber.onError(new Throwable(POLY_FAILD, new Throwable(ret, new Throwable(tBaseBean.getDesc()))));
                if (!this.subscriber.isUnsubscribed()) {
                    this.subscriber.unsubscribe();
                }
                return null;
            }
        }
    }

    /**
     * 健康2.0 ———— 2.6获取节目视频播放地址(原接口4.1)
     *
     * @param subscriber onError()观察者
     * @return Observable
     */
    public Observable getHealthyVodMediaPlayList(String id, Subscriber subscriber) {
        Map<String, Object> map = new HashMap<>();
        map.put("programId", id);
        return iPolyManager.getHealthyVodMediaPlayList(regionCode, terminal_type, map)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new DirtyListResultFactory<Definition>(subscriber))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static final class Builder {

        /**
         * 域名、服务器地址
         */
        private String mPortalAddress;
        /**
         * PORTAL
         */
        private String mPortalType;
        /**
         * 终端类型
         */
        private String mTerminalType;
        /**
         * 区域ID
         */
        private String mRegionCode;


        public Builder() {

        }


        /**
         * 设置域名
         *
         * @param baseUrl PORTAL地址 ———— 例：http://192.168.3.20
         * @return Builder
         */
        public Builder portalAddress(String baseUrl) {
            this.mPortalAddress = baseUrl;
            return this;
        }

        /**
         * 设置PORTAL名
         *
         * @param portalType 接口对应PORTAL
         * @return Builder
         */
        public Builder portalType(String portalType) {
            this.mPortalType = portalType;
            return this;
        }

        /**
         * 设置终端类型 terminal_type
         *
         * @param terminal_type 终端类型terminal_type
         * @return Builder
         */
        public Builder terminalType(String terminal_type) {
            this.mTerminalType = terminal_type;
            return this;
        }

        /**
         * 设置区域ID
         *
         * @param regionCode 区域ID
         * @return Builder
         */
        public Builder regionCode(String regionCode) {
            this.mRegionCode = regionCode;
            return this;
        }


        public PolyManager build() {
            mPolyManager = new PolyManager(mPortalAddress,
                    mTerminalType, mRegionCode);
            return mPolyManager;
        }
    }
}
